package com.fowo.api.walmart.api;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.datainterface.constants.Constants;
import com.fowo.api.datainterface.service.impl.DatainterfaceServiceImpl;
import com.fowo.api.entity.*;
import com.fowo.api.mapper.ParilistMapper;
import com.fowo.api.mapper.SysCountryMapper;
import com.fowo.api.model.wfs.cargo.WfsCargoVo;
import com.fowo.api.model.wfs.cargo.item.WfsCargoItemItemVo;
import com.fowo.api.service.SysCountryService;
import com.fowo.api.service.WFSAddressService;
import com.fowo.api.service.impl.*;
import com.fowo.api.walmart.entity.InboundShipmentBo;
import com.fowo.api.walmart.entity.OrderItemBo;
import com.fowo.api.walmart.entity.ReturnAddressBo;
import com.fowo.api.walmart.util.WalmartUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

@Component
@Slf4j
public class WalmartShipmentApi {
    @Resource
    private ShopInfoServiceImpl shopInfoService;
    @Resource
    private WFSAddressServiceImpl wfsAddressService;
    @Resource
    private WalmartListingServiceImpl walmartListingService;
    @Resource
    private TmpWfsCargoServiceImpl tmpWfsCargoService;
    @Resource
    private TmpWfsCargoItemServiceImpl tmpWfsCargoItemService;
    @Resource
    private ParilistMapper parilistMapper;
    @Resource
    private DatainterfaceServiceImpl datainterfaceService;

    private static final String INBOUND_SHIPMENT_URL = "https://marketplace.walmartapis.com/v3/fulfillment/inbound-shipments";
    private static final String INBOUND_SHIPMENT_ITEMS_URL = "https://marketplace.walmartapis.com/v3/fulfillment/inbound-shipment-items";

    private List<SysCountry> countryList = new ArrayList<>();

    /**
     * 创建WFS货件
     * @param wfsCargoVo
     * @return
     */
    public JSONObject createInboundShipment(WfsCargoVo wfsCargoVo){
        ShopInfo shopInfo = shopInfoService.getById(wfsCargoVo.getShopId());
        String token = WalmartUtil.getToken(shopInfo.getMarketplaceId(),shopInfo.getRefreshToken());
        Map<String,Object> header = new HashMap<>();
        header.put("WM_SEC.ACCESS_TOKEN",token);
        header.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());
        header.put("WM_SVC.NAME","Walmart Marketplace");
        header.put("Accept","application/json");
        header.put("Content-Type","application/json");

        InboundShipmentBo inboundShipmentBo = buildInboundShipment(wfsCargoVo);

//        Object result = WalmartUtil.getBaseAspect().httpRequest(INBOUND_SHIPMENT_URL, HttpMethod.POST, JSONUtil.toJsonStr(inboundShipmentBo), header, Object.class, Constants.Write, StrUtil.EMPTY);
        Object result = datainterfaceService.executeInterface(null, "EC00536", null, JSONUtil.toJsonStr(inboundShipmentBo), header);
        JSONObject body = JSONUtil.parseObj(result);
        log.error("创建WFS货件返回参数：{}",JSONUtil.toJsonStr(body));
        return body;
    }

    /**
     * 构建货件对象
     * @param wfsCargoVo
     * @return
     */
    public InboundShipmentBo buildInboundShipment(WfsCargoVo wfsCargoVo){
        List<OrderItemBo> orderItems = new ArrayList<>();
        for(WfsCargoItemItemVo itemVo : wfsCargoVo.getItems()){
            final WalmartListing walmartListing = walmartListingService.getOne(Wrappers.lambdaQuery(WalmartListing.class)
                    .eq(WalmartListing::getMsku, itemVo.getMsku())
                    .eq(WalmartListing::getSid, wfsCargoVo.getShopId()));
            OrderItemBo orderItemBo = new OrderItemBo();
            orderItemBo.setProductId(walmartListing.getItemId());
            orderItemBo.setProductType(itemVo.getProductType());
            orderItemBo.setSku(itemVo.getMsku());
            orderItemBo.setItemDesc(itemVo.getProductDescribe());
            orderItemBo.setItemQty(itemVo.getDeclareNum());
            orderItemBo.setVendorPackQty(itemVo.getBoxNum());
            orderItemBo.setInnerPackQty(itemVo.getSingleboxquantity());
            orderItemBo.setExpectedDeliveryDate(DateUtil.format(itemVo.getEstimatedExpirationTime(), DatePattern.UTC_PATTERN));
            orderItems.add(orderItemBo);
        }

        final WFSAddress address = wfsAddressService.getById(wfsCargoVo.getReturnAddresses());
        ReturnAddressBo returnAddressBo = new ReturnAddressBo();
        returnAddressBo.setCountryCode(address.getCountry());
        returnAddressBo.setStateCode(address.getArea());
        returnAddressBo.setCity(address.getCity());
        returnAddressBo.setAddressLine1(address.getStreetDetail());
        returnAddressBo.setPostalCode(address.getPostalCode());

        InboundShipmentBo inboundShipmentBo = new InboundShipmentBo();
        inboundShipmentBo.setInboundOrderId(wfsCargoVo.getInBoundOrderId());
        inboundShipmentBo.setReturnAddress(returnAddressBo);
        inboundShipmentBo.setOrderItems(orderItems);
        return inboundShipmentBo;
    }

    /**
     * 取消货件
     * @param shopId
     * @param inboundOrderId
     * @return
     */
    public String cancelInboundShipment(Long shopId,String inboundOrderId){
        ShopInfo shopInfo = shopInfoService.getById(shopId);
        String token = WalmartUtil.getToken(shopInfo.getMarketplaceId(),shopInfo.getRefreshToken());
        Map<String,Object> header = new HashMap<>();
        header.put("WM_SEC.ACCESS_TOKEN",token);
        header.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());
        header.put("WM_SVC.NAME","Walmart Marketplace");
        header.put("Accept","application/json");
        header.put("Content-Type","application/json");

//        Object result = WalmartUtil.getBaseAspect().httpRequest(INBOUND_SHIPMENT_URL+"/"+inboundOrderId, HttpMethod.DELETE, null, header, Object.class, Constants.Write, StrUtil.EMPTY);
        Map<String,Object> params = new HashMap<>();
        params.put("path",inboundOrderId);
        Object result = datainterfaceService.executeInterface(null, "EC00537", null, params, header);
        JSONObject body = JSONUtil.parseObj(result);
        return body.getStr("status");
    }

    /**
     * 获取货件列表
     */
    public List<TmpWfsCargo> getShipments(){

        final List<ShopInfo> shopInfos = shopInfoService.list(Wrappers.lambdaQuery(ShopInfo.class)
                .eq(ShopInfo::getPlatform, "Walmart")
                .eq(ShopInfo::getSellerAuthStatus, "SQ01"));
        List<TmpWfsCargo> tmpList = new ArrayList<>();
        for(ShopInfo shopInfo : shopInfos){
            String token = WalmartUtil.getToken(shopInfo.getMarketplaceId(),shopInfo.getRefreshToken());
            Map<String,Object> header = new HashMap<>();
            header.put("WM_SEC.ACCESS_TOKEN",token);
            header.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());
            header.put("WM_SVC.NAME","Walmart Marketplace");

            Integer limit = 100;
            Map<String,Object> param = new HashMap<>();
            param.put("offset","0");
            param.put("limit",limit);

//            Object result = WalmartUtil.getBaseAspect().httpRequest(INBOUND_SHIPMENT_URL+"?offset=0&limit="+limit, HttpMethod.GET, null, header, Object.class, Constants.Read, StrUtil.EMPTY);
            Object result = datainterfaceService.executeInterface(null, "EC00538", null, param, header);
            JSONObject body = JSONUtil.parseObj(result);

            log.error("货件返回参数：{}",JSONUtil.toJsonStr(body));
            final JSONArray payload = body.getJSONArray("payload");
            tmpList.addAll(buildTmpWfsCargo(payload,shopInfo));

            final JSONObject headers = body.getJSONObject("headers");
            final Integer totalCount = headers.getInt("totalCount");
            if(totalCount > limit){
                int pages = totalCount/limit;
                if(totalCount%limit > 0){
                    pages += 1;
                }
                for(int i = 1 ; i <= pages ; i++){
                    tmpList.addAll(getNext(header,headers,i,shopInfo));
                }
            }

        }
        tmpWfsCargoService.saveBatch(tmpList);
        return tmpList;
    }

    public List<TmpWfsCargo> getNext(Map<String,Object> header,JSONObject headers,Integer offset,ShopInfo shopInfo){
        Map<String,Object> param = new HashMap<>();
//        Integer offset = headers.getInt("offset")+1;
        param.put("offset",offset.toString());
        param.put("limit",headers.getStr("limit"));
//        Object result = WalmartUtil.getBaseAspect().httpRequest(INBOUND_SHIPMENT_URL+"?offset="+offset+"&limit="+headers.getStr("limit"), HttpMethod.GET, JSONUtil.toJsonStr(param), header, Object.class, Constants.Read, StrUtil.EMPTY);
        Object result = datainterfaceService.executeInterface(null, "EC00538", null, param, header);
        JSONObject body = JSONUtil.parseObj(result);
        final JSONArray payload = body.getJSONArray("payload");

        return buildTmpWfsCargo(payload,shopInfo);
    }

    public List<TmpWfsCargo> getShipmentsByShop(Long shopId,List<String> shipmentIds){
        final ShopInfo shopInfo = shopInfoService.getById(shopId);
        List<TmpWfsCargo> tmpList = new ArrayList<>();
        for(String shipmentId : shipmentIds){
            String token = WalmartUtil.getToken(shopInfo.getMarketplaceId(),shopInfo.getRefreshToken());
            Map<String,Object> header = new HashMap<>();
            header.put("WM_SEC.ACCESS_TOKEN",token);
            header.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());
            header.put("WM_SVC.NAME","Walmart Marketplace");

            Integer limit = 100;
            Map<String,Object> param = new HashMap<>();
            param.put("offset","0");
            param.put("limit",limit);
            param.put("shipmentId",shipmentId);
//            Object result = WalmartUtil.getBaseAspect().httpRequest(INBOUND_SHIPMENT_URL+"?offset=0&limit="+limit+"&shipmentId="+shipmentId, HttpMethod.GET, null, header, Object.class, Constants.Read, StrUtil.EMPTY);
            Object result = datainterfaceService.executeInterface(null, "EC00538", null, param, header);
            JSONObject body = JSONUtil.parseObj(result);

            log.error("货件返回参数：{}",JSONUtil.toJsonStr(body));
            final JSONArray payload = body.getJSONArray("payload");
            tmpList.addAll(buildTmpWfsCargo(payload,shopInfo));

//            final JSONObject headers = body.getJSONObject("headers");
//            final Integer totalCount = headers.getInt("totalCount");
//            if(totalCount > limit){
//                int pages = totalCount/limit;
//                if(totalCount%limit > 0){
//                    pages += 1;
//                }
//                for(int i = 1 ; i <= pages ; i++){
//                    tmpList.addAll(getNext(header,headers,i,shopInfo));
//                }
//            }
        }
        tmpWfsCargoService.saveBatch(tmpList);
        return tmpList;
    }

    /**
     * 构建货件临时表数据
     * @param payload
     * @param shopInfo
     * @return
     */
    public List<TmpWfsCargo> buildTmpWfsCargo(JSONArray payload,ShopInfo shopInfo){
        List<TmpWfsCargo> list = new ArrayList<>();
        for(int i = 0 ; i < payload.size() ; i++){
            final JSONObject jsonObject = payload.getJSONObject(i);
            final TmpWfsCargo tmpWfsCargo = jsonObject.toBean(TmpWfsCargo.class);
            tmpWfsCargo.setSid(shopInfo.getId());
            tmpWfsCargo.setCountryName(shopInfo.getMid());
            tmpWfsCargo.setCreateTime(new Date());
            tmpWfsCargo.setLastUpdateTime(new Date());
            final JSONObject shipToAddress = jsonObject.getJSONObject("shipToAddress");
            if(null != shipToAddress){
                tmpWfsCargo.setToFcName(shipToAddress.getStr("fcName"));
                tmpWfsCargo.setToAddressLine1(shipToAddress.getStr("addressLine1"));
                tmpWfsCargo.setToAddressLine2(shipToAddress.getStr("addressLine2"));
                tmpWfsCargo.setToCity(shipToAddress.getStr("city"));
                tmpWfsCargo.setToStateCode(shipToAddress.getStr("stateCode"));
                tmpWfsCargo.setToCountryCode(shipToAddress.getStr("countryCode"));
                tmpWfsCargo.setToPostalCode(shipToAddress.getStr("postalCode"));

            }
            final JSONObject returnAddress = jsonObject.getJSONObject("returnAddress");
            if(null != returnAddress){
                tmpWfsCargo.setReturnAddressLine1(returnAddress.getStr("addressLine1"));
                tmpWfsCargo.setReturnAddressLine2(returnAddress.getStr("addressLine2"));
                tmpWfsCargo.setReturnCity(returnAddress.getStr("city"));
                tmpWfsCargo.setReturnStateCode(returnAddress.getStr("stateCode"));
                tmpWfsCargo.setReturnCountryCode(returnAddress.getStr("countryCode"));
                tmpWfsCargo.setReturnPostalCode(returnAddress.getStr("postalCode"));
            }
            list.add(tmpWfsCargo);
        }
        return list;
    }

    /**
     * 获取货件详情信息
     * @param shipments
     * @return
     */
    public List<TmpWfsCargoItem> getShipmentItems(List<TmpWfsCargo> shipments){
        final List<ShopInfo> shopInfos = shopInfoService.list(Wrappers.lambdaQuery(ShopInfo.class)
                .eq(ShopInfo::getPlatform, "Walmart")
                .eq(ShopInfo::getSellerAuthStatus, "SQ01"));
        List<TmpWfsCargoItem> itemList = new ArrayList<>();
        for(TmpWfsCargo tmpWfsCargo : shipments){
            ShopInfo shopInfo = shopInfos.stream().filter(s -> s.getId().equals(tmpWfsCargo.getSid())).findFirst().orElse(null);
            if(null == shopInfo){
                continue;
            }
            String token = WalmartUtil.getToken(shopInfo.getMarketplaceId(),shopInfo.getRefreshToken());
            Map<String,Object> header = new HashMap<>();
            header.put("WM_SEC.ACCESS_TOKEN",token);
            header.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());
            header.put("WM_SVC.NAME","Walmart Marketplace");

            Map<String,Object> param = new HashMap<>();
            param.put("shipmentId",tmpWfsCargo.getShipmentId());

//            Object result = WalmartUtil.getBaseAspect().httpRequest(INBOUND_SHIPMENT_ITEMS_URL+"?shipmentId="+tmpWfsCargo.getShipmentId(), HttpMethod.GET, null, header, Object.class, Constants.Read, StrUtil.EMPTY);
            Object result = datainterfaceService.executeInterface(null, "EC00539", null, param, header);
            JSONObject body = JSONUtil.parseObj(result);
            final JSONArray payload = body.getJSONArray("payload");
            log.error("货件详情返回参数：{}",JSONUtil.toJsonStr(body));

            itemList.addAll(buildTmpWfsCargoItem(payload,shopInfo));

//            final JSONObject headers = body.getJSONObject("headers");
//            final Integer totalCount = headers.getInt("totalCount");
//            if(totalCount > limit){
//                int pages = totalCount/limit;
//                if(totalCount%limit > 0){
//                    pages += 1;
//                }
//                for(int i = 1 ; i <= pages ; i++){
//                    itemList.addAll(getItemNext(header,headers,i,shopInfo,tmpWfsCargo.getShipmentId()));
//                }
//            }

        }
        tmpWfsCargoItemService.saveBatch(itemList);
        return itemList;

    }

    /**
     * 详情下一页
     * @param header
     * @param headers
     * @param offset
     * @param shopInfo
     * @param shipmentId
     * @return
     */
    public List<TmpWfsCargoItem> getItemNext(HttpHeaders header,JSONObject headers,Integer offset,ShopInfo shopInfo,String shipmentId){
        Map<String,Object> param = new HashMap<>();
//        Integer offset = headers.getInt("offset")+1;
        param.put("offset",offset.toString());
        param.put("limit",headers.getStr("limit"));
        param.put("shipmentId",shipmentId);
        Object result = WalmartUtil.getBaseAspect().httpRequest(INBOUND_SHIPMENT_ITEMS_URL, HttpMethod.GET, JSONUtil.toJsonStr(param), header, Object.class, Constants.Read, StrUtil.EMPTY);
        JSONObject body = JSONUtil.parseObj(result);
        final JSONArray payload = body.getJSONArray("payload");
        log.error("货件详情返回参数：{}",JSONUtil.toJsonStr(body));
        return buildTmpWfsCargoItem(payload,shopInfo);
    }

    /**
     * 构建货件详情数据
     * @param payload
     * @param shopInfo
     * @return
     */
    public List<TmpWfsCargoItem> buildTmpWfsCargoItem(JSONArray payload,ShopInfo shopInfo){
        List<TmpWfsCargoItem> result = new ArrayList<>();
        final List<Parilist> parilists = parilistMapper.selectList(Wrappers.lambdaQuery(Parilist.class).eq(Parilist::getShopId, shopInfo.getId()).eq(Parilist::getType,"1"));
        for(int i = 0 ; i < payload.size() ; i++){
            final JSONObject jsonObject = payload.getJSONObject(i);
            final TmpWfsCargoItem tmpWfsCargoItem = jsonObject.toBean(TmpWfsCargoItem.class);
            Parilist parilist = parilists.stream().filter(p -> p.getMsku().equals(tmpWfsCargoItem.getSku())).findAny().orElse(null);
            if(null != parilist){
                tmpWfsCargoItem.setImg(parilist.getImg());
                tmpWfsCargoItem.setProductName(parilist.getProductId());
                tmpWfsCargoItem.setLocalSku(parilist.getSku());
            }
            result.add(tmpWfsCargoItem);
        }
        return result;
    }
}
